import wx
from decimal import Decimal as Dec
import decimal

from DataTool import DataTool

class DiaTable2add(wx.Dialog):
    
    inputnamelist = (
                '费用名称',
                '费用费率',
                '费用描述',
                '费用公式',
                )

    prenamelist = (
                '生成名称',
                '生成费率',
                '生成描述',
                '生成价格',
                )
    ret = {
            '费用名称':None,
            '费用费率':None,
            '费用描述':None,
            '费用公式':None,
        }

    def __init__(self, parent, title, *args, **kwargs):
        super().__init__(parent, -1, title)
        self.data = kwargs.get('data', ['', '', '', ''])
        self.namefrz = kwargs.get('namefrz', 0)
        topLbl = wx.StaticText(self, -1, "新增措施费表单")
        topLbl.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))
        mainsizer = wx.BoxSizer(orient=wx.VERTICAL)
        secsizer = wx.BoxSizer(orient=wx.HORIZONTAL)
        inputsizer = wx.StaticBoxSizer(wx.VERTICAL, self, '数据表单')
        presizer = wx.StaticBoxSizer(wx.VERTICAL, self, '数据预览')
        btnsizer = wx.BoxSizer(orient=wx.HORIZONTAL)

        mainsizer.Add(topLbl, 0, wx.ALL|wx.CENTRE, 5)
        mainsizer.Add(wx.StaticLine(self), 0,
                wx.EXPAND|wx.TOP|wx.BOTTOM, 5)

        mainsizer.Add(secsizer, 0, wx.ALL, 5)
        secsizer.Add(inputsizer, 0, wx.ALL, 5)
        secsizer.Add(presizer, 0, wx.ALL, 5)

        mainsizer.Add(wx.StaticLine(self), 0,
                wx.EXPAND|wx.TOP|wx.BOTTOM, 5)
        mainsizer.Add(btnsizer, 0, wx.ALL, 5)

        self.CreateEntry(self.inputnamelist, inputsizer, flag=1)
        self.CreateEntry(self.prenamelist, presizer)


        btnsave = wx.Button(self, -1, "保存(&S)")
        btncal = wx.Button(self, -1, "取消(&C)")
        self.Bind(wx.EVT_BUTTON, self.OnSave, btnsave)
        self.Bind(wx.EVT_BUTTON, self.OnCancel, btncal)


        btnsizer.Add((140,20), 1)
        btnsizer.Add(btnsave,0)
        btnsizer.Add((140,20), 1)
        btnsizer.Add(btncal)
        btnsizer.Add((140,20), 1)

        self.SetSizer(mainsizer)
        mainsizer.Fit(self)
        mainsizer.SetSizeHints(self)

    #     self.HandEvent()

    # def HandEvent(self):
    #     for name in self.inputnamelist:
    #         eventtype = wx.EVT_TEXT.typeId
    #         obj = wx.FindWindowByName(name)
    #         thisid = obj.GetId()
    #         event = wx.CommandEvent(eventtype, thisid)
    #         wx.PostEvent(obj, event)

    def CreateEntry(self, namelist, sizer, flag=0):
        addrSizer = wx.FlexGridSizer(cols=2, hgap=5, vgap=5)
        addrSizer.AddGrowableCol(1)
        for row, i in enumerate(namelist):
            static = wx.StaticText(self, -1, i,)
            if flag == 1:
                if self.namefrz == 1 and row == 0:
                    text = wx.TextCtrl(self, -1, size=(200,-1), name=i, value=str(self.data[row]), style=wx.TE_READONLY)
                else:
                    text = wx.TextCtrl(self, -1, size=(200,-1), name=i, value=str(self.data[row]))
                self.Bind(wx.EVT_TEXT, self.OnText, text)
            else:
                text = wx.TextCtrl(self, -1, size=(200,-1), name=i, style=wx.TE_READONLY)
            addrSizer.Add(static, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
            addrSizer.Add(text, 0, wx.EXPAND)
        sizer.Add(addrSizer, 0, wx.ALL, 5)

    def OnText(self, event):
        obj = event.GetEventObject()
        index = self.inputnamelist.index(obj.GetName())
        if index == 0:
            writeobj = self.FindWindowByName(self.prenamelist[index])
            writeobj.Value = obj.GetLineText(0)
        elif index == 1:
            writeobj = self.FindWindowByName(self.prenamelist[index])
            try:
                writeobj.Value = str(float(Dec(str(obj.GetLineText(0)))*100)) + '%'
            except decimal.InvalidOperation:
                writeobj.Value = '0'
            obj = self.FindWindowByName(self.inputnamelist[2])
            index = 2
        if index == 2:
            writeobj = self.FindWindowByName(self.prenamelist[index])
            try:
                writeobj.Value = obj.GetLineText(0)%(float(self.FindWindowByName('费用费率').Value)*100)
            except TypeError:
                writeobj.Value = obj.GetLineText(0)
            except ValueError:
                writeobj.Value = obj.GetLineText(0)
            obj = self.FindWindowByName(self.inputnamelist[3])
            index = 3
        if index == 3:
            writeobj = self.FindWindowByName(self.prenamelist[index])
            thisformula = obj.GetLineText(0)
            thisformula = DataTool.table2parseformula(thisformula)
            for index, value in enumerate(thisformula):
                if hasattr(self, 'initdata') and self.initdata is not None and value in self.initdata:
                    thisformula[index] = self.initdata[value]
                if value == '费率':
                    thisformula[index] = float(self.FindWindowByName('费用费率').Value)
                if hasattr(self, 'table2flist') and self.table2flist is not None:
                    for row in self.table2flist:
                        if value == row[0]:
                            thisformula[index] = row[1]
            try:
                thisformula = DataTool.listadddec(thisformula)
                thisformula = DataTool.list2str(thisformula)
                filldata = eval(thisformula)
                filldata = Dec(str(float(filldata)))
            except SyntaxError:
                thisformula = DataTool.list2str(thisformula)
                filldata = thisformula
            except ValueError:
                thisformula = DataTool.list2str(thisformula)
                filldata = thisformula
            writeobj.Value = str(filldata)
    
    def OnSave(self, event):
        for key in self.ret:
            writeobj = self.FindWindowByName(key)
            self.ret[key] = writeobj.Value
        self.EndModal(retCode=1)

    def OnCancel(self, event):
        self.EndModal(retCode=5101)

    def ShowModal(self):
        ret = super().ShowModal()
        if ret == 5101:
            return ret
        elif ret == 1:
            return self.ret
        else:
            return 5101


class DiaTable2Rate(wx.Dialog):
    tax = [
            '施工税率',
            '材料税率',
            '服务税率',
            ]

    discountname = [
        '施工折扣',
        ]

    base = ['工地距离', '大型机械距离', '大型机械吨位']

    ret = {
            '折扣':{'施工折扣':0},
            '税率':{'施工税率':0,'材料税率':0,'服务税率':0,},
            '基础数据':{'工地距离':0, '大型机械距离':0, '大型机械吨位':0,},
            '费率':dict(),
            '自定义':dict()
            }
    def __init__(self, parent, title, *args, **kwargs):
        # kwargs 表二费率 rate
        # kwargs 折扣 discount discountd discounts 
        # kwargs 税率 contax 为施工单位增值税 matetax 为材料增值税 servtax 为服务费增值税
        # kwargs mach_dis为大型机械调遣距离（km）； ton为大型机械吨位；sc2en_dis为现场到企业距离（km）；
        self.rate = kwargs.get('rate', dict())
        self.custom = kwargs.get('custom', dict())
        self.discount = kwargs.get('discount', 100)
        self.contax = kwargs.get('contax', 100)
        self.matetax = kwargs.get('matetax', 100)
        self.servtax = kwargs.get('servtax', 100)
        self.mach_dis = kwargs.get('mach_dis', 0)
        self.sc2en_dis = kwargs.get('sc2en_dis', 0)
        self.ton = kwargs.get('ton', 0)
        self.ret['费率'] = self.rate
        self.ret['自定义'] = self.custom

        super().__init__(parent, -1, title)
        topLbl = wx.StaticText(self, -1, "表二费率调整表单")
        topLbl.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))
        mainsizer = wx.GridBagSizer(hgap=5, vgap=5)
        btnsizer = wx.BoxSizer(orient=wx.HORIZONTAL)
        discsizer = wx.StaticBoxSizer(wx.HORIZONTAL, self, '折扣')
        taxsizer = wx.StaticBoxSizer(wx.HORIZONTAL, self, '税率')
        basesizer = wx.StaticBoxSizer(wx.HORIZONTAL, self, '基础数据')
        ratesizer = wx.StaticBoxSizer(wx.VERTICAL, self, '费率')
        secratesizer = wx.GridBagSizer(hgap=5, vgap=5)
        rgsizer = wx.StaticBoxSizer(wx.HORIZONTAL, self, '人工费')
        clsizer = wx.StaticBoxSizer(wx.HORIZONTAL, self, '材料费')
        cssizer = wx.StaticBoxSizer(wx.HORIZONTAL, self, '措施费')
        jjsizer = wx.StaticBoxSizer(wx.HORIZONTAL, self, '间接费')
        gfsizer = wx.StaticBoxSizer(wx.HORIZONTAL, self, '规费')
        qysizer = wx.StaticBoxSizer(wx.HORIZONTAL, self, '企业管理费')
        lrsizer = wx.StaticBoxSizer(wx.HORIZONTAL, self, '利润')

        mainsizer.Add(topLbl, pos=(0,0), span=(1,3),
                flag=wx.ALL|wx.ALIGN_CENTER, border=5)
        mainsizer.Add(wx.StaticLine(self), pos=(1,0), span=(1,3),
                flag=wx.EXPAND|wx.TOP|wx.BOTTOM, border=5)
        # *****************************************************************************
        #  折扣
        mainsizer.Add(discsizer, pos=(2,0),
                flag=wx.EXPAND|wx.ALL, border=5)

        self.genhorizwin(['施工折扣'], discsizer)
        # *****************************************************************************
        #  税率
        mainsizer.Add(taxsizer, pos=(2,1),
                flag=wx.EXPAND|wx.ALL, border=5)
        self.genhorizwin(['施工税率', '材料税率', '服务税率'], taxsizer)
        # *****************************************************************************
        #  基础数据
        mainsizer.Add(basesizer, pos=(2,2),
                flag=wx.ALL, border=5)
        self.genhorizwin(['工地距离', '大型机械距离', '大型机械吨位'], basesizer)
        # *****************************************************************************
        # 表二折扣和 费率
        mainsizer.Add(ratesizer, pos=(3,0), span=(1,3),
                flag=wx.EXPAND|wx.ALL, border=5)
        ratesizer.Add(secratesizer,
                flag=wx.EXPAND|wx.ALL, border=5)
        secratesizer.Add(rgsizer, pos=(0,0),
                flag=wx.EXPAND|wx.ALL, border=5)
        self.genhorizwin(['技工费', '普工费'], rgsizer)

        secratesizer.Add(clsizer, pos=(0,1),
                flag=wx.EXPAND|wx.ALL, border=5)
        self.genhorizwin(['辅助材料费'], clsizer)

        secratesizer.Add(gfsizer, pos=(0,2),
                flag=wx.EXPAND|wx.ALL, border=5)
        self.genhorizwin(['工程排污费', '社会保障费', '住房公积金', '危险作业意外伤害保险费'], gfsizer)

        secratesizer.Add(qysizer, pos=(0,3),
                flag=wx.EXPAND|wx.ALL, border=5)
        self.genhorizwin(['企业管理费'], qysizer)

        secratesizer.Add(lrsizer, pos=(0,4),
                flag=wx.EXPAND|wx.ALL, border=5)
        self.genhorizwin(['利润'], lrsizer)

        secratesizer.Add(cssizer, pos=(1,0), span=(1,5),
                flag=wx.EXPAND|wx.ALL, border=5)
        seccssizer = wx.GridBagSizer(hgap=5, vgap=5)
        cssizer.Add(seccssizer)
        
        data = self.getmeasures()
        if data is not None:
            self.genbagsizer(data, seccssizer)
        # *****************************************************************************
        # 按钮
        mainsizer.Add(wx.StaticLine(self), pos=(4,0), span=(1,3),
                flag=wx.EXPAND|wx.TOP|wx.BOTTOM, border=5)
        btnsizer = wx.BoxSizer(orient=wx.HORIZONTAL)
        mainsizer.Add(btnsizer, pos=(5,0), span=(1,3),
                flag=wx.EXPAND|wx.ALL, border=5)

        btnsave = wx.Button(self, -1, "保存(&S)")
        btncal = wx.Button(self, -1, "取消(&C)")
        self.Bind(wx.EVT_BUTTON, self.OnSave, btnsave)
        self.Bind(wx.EVT_BUTTON, self.OnCancel, btncal)

        btnsizer.Add((140,20), 1)
        btnsizer.Add(btnsave,0)
        btnsizer.Add((140,20), 0)
        btnsizer.Add(btncal)
        btnsizer.Add((140,20), 1)

        self.SetSizer(mainsizer)
        mainsizer.Fit(self)
        mainsizer.SetSizeHints(self)

    def OnSave(self, event, tdict=dict(), flag=0):
        specfee = [
                '施工队伍调遣费',
                '大型施工机械调遣费',
                ]
        if flag == 0:
            tdict = self.ret
        for key in tdict:
            if isinstance(tdict[key], dict) and key != '自定义':
                self.OnSave(event, tdict[key], 1)
            elif key == '自定义':
                pass
            else:
                writeobj = self.FindWindowByName(key)
                if writeobj is None:
                    DataTool.feefillin(tdict, key, '0')
                elif key in specfee:
                    writeobj1 = self.FindWindowByName(key+'定额')
                    writeobj2 = self.FindWindowByName(key+'数量')
                    v1 = writeobj1.Value
                    v2 = writeobj2.Value
                    if DataTool.isnum(v1) and DataTool.isnum(v2):
                        v1 = float(v1)
                        v2 = float(v2)
                    else:
                        print('haha')
                    DataTool.feefillin(tdict, key, [v1, v2])
                else:
                    if DataTool.isnum(writeobj.Value):
                        v1 = float(writeobj.Value)
                    else:
                        print('haha')
                    DataTool.feefillin(tdict, key, v1)
        if flag == 0:
            self.EndModal(retCode=1)

    def OnCancel(self, event):
        self.EndModal(retCode=5101)

    def ShowModal(self):
        ret = super().ShowModal()
        if ret == 5101:
            return ret
        elif ret == 1:
            return self.ret
        else:
            return 5101

    def OnCustom(self, event):
        selection = event.GetSelection()
        obj = event.GetEventObject()
        name = obj.GetName()
        name = name.split('自定义')[0]
        if selection == 0:
            DataTool.feefillin(self.ret['自定义'], name, 1)
        else:
            DataTool.feefillin(self.ret['自定义'], name, 0)

    def genhorizwin(self, data, sizer):
        for name in data:
            value = DataTool.recursionsearch(self.rate, name)
            if value is None:
                value = ''
            if name in self.tax:
                index = self.tax.index(name)
                if index == 0:
                    value = self.contax
                elif index == 1:
                    value = self.matetax
                else:
                    value = self.servtax
            elif name in self.base:
                index = self.base.index(name)
                if index == 0:
                    value = self.sc2en_dis
                elif index == 1:
                    value = self.mach_dis
                else:
                    value = self.ton

            if name in self.discountname:
                value = self.discount
            value = str(value)
            text = wx.StaticText(self, -1, name)
            textctrl = wx.TextCtrl(self, -1, size=(50,-1), name=name, value=value)
            sizer.Add(text, 0, wx.ALL|wx.ALIGN_CENTER, 2)
            sizer.Add(textctrl, 0, wx.ALL, 2)

    def getmeasures(self):
        data = DataTool.recursionsearch(self.rate, '措施费')
        return data

    def genbagsizer(self, data, sizer):
        colnum = 7
        specfee = [
                '施工队伍调遣费',
                '大型施工机械调遣费',
                ]
        skipnames = [
                    '施工用水电蒸汽费',
                    '工程排污费',
                    '运土费',
                    ]
        thissizer = 0
        for name in specfee:
            if name in data:
                thissizer = wx.StaticBoxSizer(wx.HORIZONTAL, self, '特殊')
                sizer.Add(thissizer, pos=(0, 0), span=(0, 12),
                    flag=wx.ALIGN_LEFT|wx.ALL, border=2)
                break

        speccount = 0
        for index, value in enumerate(data):
            if thissizer == 0:
                row = index // colnum
                col = index % colnum
            else:
                row = (index // colnum) + 1
                col = index % colnum
                

            if value not in specfee and value not in skipnames:
                values = DataTool.recursionsearch(self.rate, value)
                values = str(values)
                text = wx.StaticText(self, -1, value)
                textctrl = wx.TextCtrl(self, -1, size=(50,-1), name=value, value=values)
                sizer.Add(text, pos=(row, col*2), 
                    flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, border=2)
                sizer.Add(textctrl, pos=(row, col*2+1), 
                    flag=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, border=2)
            elif value in skipnames:
                pass
            else:
                values = DataTool.recursionsearch(self.rate, value)
                values1 = str(values[0])
                values2 = str(values[1])
                text0 = wx.StaticText(self, -1, value)
                text = wx.StaticText(self, -1, '定额')
                textctrl = wx.TextCtrl(self, -1, size=(50,-1), name=value + '定额', value=values1)
                text2 = wx.StaticText(self, -1, '数量')
                textctrl2 = wx.TextCtrl(self, -1, size=(50,-1), name=value + '数量', value=values2)
                checkbox = wx.CheckBox(self, -1, label='自定义', name=value + '自定义')
                i = DataTool.recursionsearch(self.custom, value)
                if i == 0:
                    checkbox.SetValue(True)
                else:
                    checkbox.SetValue(False)
                self.Bind(wx.EVT_CHECKBOX, self.OnCustom, checkbox)
                thissizer.Add(text0, 
                    flag=wx.ALL|wx.ALIGN_CENTER_VERTICAL, border=2)
                thissizer.Add(text, 
                    flag=wx.ALL|wx.ALIGN_CENTER_VERTICAL, border=2)
                thissizer.Add(textctrl,
                    flag=wx.ALL|wx.ALIGN_CENTER_VERTICAL, border=2)
                thissizer.Add(text2,
                    flag=wx.ALL|wx.ALIGN_CENTER_VERTICAL, border=2)
                thissizer.Add(textctrl2,
                    flag=wx.ALL|wx.ALIGN_CENTER_VERTICAL, border=2)
                thissizer.Add(checkbox,
                    flag=wx.ALL|wx.ALIGN_CENTER_VERTICAL, border=2)
                thissizer.Add((40, 40),
                    flag=wx.ALL|wx.ALIGN_CENTER_VERTICAL, border=2)
                speccount += 1

if __name__ == "__main__":

    rate_example = {'直接费':
                        {'直接工程费':
                            {'人工费':
                                {'技工费': 1, '普工费': 1},
                            '材料费':
                                {'主要材料费': 1, '辅助材料费': 1},
                            '机械使用费': 1,
                            '仪表使用费': 1,
                            },
                        '措施费':
                            {
                                '文明施工费':1,
                                '工地器材搬运费':1,
                                '工程干扰费':1,
                                '工程点交、场地清理费':1,
                                '临时设施费':1,
                                '工程车辆使用费':1,
                                '夜间施工增加费':1,
                                '冬雨季施工增加费':1,
                                '生产工具用具使用费':1,
                                '施工用水电蒸汽费':1,
                                '特殊地区施工增加费':1,
                                '已完工程及设备保护费':1,
                                '运土费':0,
                                '施工队伍调遣费': [1, 1],
                                '大型施工机械调遣费': [1, 1],
                            },
                        },
                    '间接费':
                        {
                            '规费':
                            {
                                '工程排污费':0,
                                '社会保障费':1,
                                '住房公积金':1,
                                '危险作业意外伤害保险费':1.00,
                            },
                            '企业管理费':1.4,
                        },
                    '利润':1.0,
                    '销项税额':11.0,
                    }

    data = {
            '文明施工费':1,
            '工地器材搬运费':1,
            '工程干扰费':1,
            '工程点交、场地清理费':1,
            '临时设施费':1,
            '工程车辆使用费':1,
            '夜间施工增加费':1,
            '冬雨季施工增加费':1,
            '生产工具用具使用费':1,
            '施工用水电蒸汽费':1,
            '特殊地区施工增加费':1,
            '已完工程及设备保护费':1,
            '运土费':0,
            '施工队伍调遣费': [1, 1],
            '大型施工机械调遣费': [1, 1],
                
            }

    disable_example = {'直接费':
                        {'直接工程费':
                            {'人工费':
                                {'技工费': 0, '普工费': 0},
                            '材料费':
                                {'主要材料费': 0, '辅助材料费': 0},
                            '机械使用费': 0,
                            '仪表使用费': 0,
                            },
                        '措施费':
                            {
                                '文明施工费':0,
                                '工地器材搬运费':0,
                                '工程干扰费':0,
                                '工程点交、场地清理费':0,
                                '临时设施费':0,
                                '工程车辆使用费':0,
                                '夜间施工增加费':0,
                                '冬雨季施工增加费':0,
                                '生产工具用具使用费':0,
                                '施工用水电蒸汽费':0,
                                '特殊地区施工增加费':0,
                                '已完工程及设备保护费':0,
                                '运土费':0,
                                '施工队伍调遣费': 1,
                                '大型施工机械调遣费': 1,
                            },
                        },
                    '间接费':
                        {
                            '规费':
                            {
                                '工程排污费':0,
                                '社会保障费':0,
                                '住房公积金':0,
                                '危险作业意外伤害保险费':0,
                            },
                            '企业管理费':0,
                        },
                    '利润':0,
                    '销项税额':0,
                    }
    class MyFrame(wx.Frame):
        def __init__(self):
            super().__init__(None, -1, 'haha', size=(200, 100))
            btn = wx.Button(self, -1, 'baba', size=(10, 10))
            self.Bind(wx.EVT_BUTTON, self.OnClick, btn)

        def OnClick(self, event):
            # modal = DiaTable2add(self, 'baba').ShowModal()
            data = [1,2,34,56]
            dia = DiaTable2Rate(self, 'haha',rate=rate_example, custom=disable_example, mech=1000, work=10000,
                mach_dis=1, ton=2, sc2en_dis=3, data=data, namefrz=1)
            modal = dia.ShowModal()
            print(modal)
            dia.Destroy()

    app = wx.App()
    MyFrame().Show()
    app.MainLoop()